package com.feri.fs.provider.core;
import com.feri.fs.provider.core.bo.FieldBo;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.resource.ClasspathResourceLoader;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName BeetlUtils
 * @Description 生成Java源文件，结合定义好模板(xxx.btl)+对应的属性的数据(变量)=输出Java源文件（entity+dao+service.intf+service.impl+controller）
 * @Author xing
 * @Date 2021/11/9 09:47
 * @Version 1.0
 */
public class BeetlUtils {
    /**
     * 模板文件对应的目录
     */
    public static final String BTL_TEMP = "btltemp";
    //定义好的模板文件，动态变为变量替换。才可以外界传递数据
    public static final String BTL_TEMP_ENTITY = "Entity.btl";
    public static final String BTL_TEMP_DAO = "Dao.btl";
    public static final String BTL_TEMP_SINTF = "ServiceIntf.btl";
    public static final String BTL_TEMP_SIMPL = "ServiceImpl.btl";
    public static final String BTL_TEMP_CONTROLLER = "Controller.btl";
    /**
     * 生成对应的源文件
     */
    public static void createSrc(Map<String,Map<String,Map<String,String>>> map,String pkname,String fname,String author,String ctime,String pname) {
        ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader(BTL_TEMP);
        Configuration cfg= null;

        {
            try {
                cfg = Configuration.defaultConfiguration();
                GroupTemplate gt = new GroupTemplate(resourceLoader,cfg);
                for (String t:map.keySet()){
                    String ename=parseClassName(t);
                    //生成实体类
                    createEntity(gt,map.get(t),pkname,t,ename,fname,author,ctime,pname);
                    //生成持久类
                    createDao(gt,pkname,ename,fname,author,ctime,pname);
                    //生成业务接口
                    createServiceIntf(gt,pkname,ename,fname,author,ctime,pname);
                    //生成业务实现
                    createServiceImpl(gt,pkname,ename,fname,author,ctime,pname);
                    //生成控制层
                    createController(gt,pkname,ename,fname,author,ctime,pname,parseParamName(t));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //生成实体类源文件
    private static void createEntity(GroupTemplate gt,Map<String,Map<String,String>> map,String pkname,String tname,String ename,String fname,String author,String ctime,String pname) throws FileNotFoundException{
        //2.获取指定模板文件的对象
        Template template = gt.getTemplate("Entity.btl");
        //3.为模板文件设置数据
        Map<String, Object> params = new HashMap<>();
        params.put("tname", tname);
        params.put("entityName", ename);
        params.put("pkname", pkname);
        params.put("ctime", ctime);
        params.put("pname", pname);
        params.put("author", fname);
        List<FieldBo> fields = new ArrayList<>();
        for (String s:map.keySet()){
            fields.add(new FieldBo(s, map.get(s).get("type"), map.get(s).get("comment"), map.get(s).get("isPK").equals("PRI")));
        }
        params.put("fields", fields);

        //4.将数据和模板绑定
        template.binding(params);
        //5.生成指定的文件

        template.renderTo(new FileOutputStream(fname+"/entity/"+ename+".java"));

    }
    /**
     * 生成通用源文件*/
    private static void createCommonSrc(Template template,String pkname,String ename,String fname,String author,String ctime,String pname,String srcpk,String srcsuf) throws FileNotFoundException {
        //1.为模板文件设置数据
        Map<String,Object> params=new HashMap<>();
        params.put("entityName",ename);
        params.put("pkname",pkname);
        params.put("author",author);
        params.put("ctime",ctime);
        params.put("pname",pname);
        //4.将数据和模板绑定
        template.binding(params);
        //5.生成指定的文件
        template.renderTo(new FileOutputStream(fname+"/"+srcpk+"/"+ename+srcsuf+".java"));
    }
    /**
     * 生成dao接口源文件*/
    private static void createDao(GroupTemplate gt,String pkname,String ename,String fname,String author,String ctime,String pname) throws FileNotFoundException {
        //1.获取指定模板文件的对象
        Template template=gt.getTemplate("Dao.btl");
        //2.生成对应的源码
        createCommonSrc(template,pkname,ename,fname,author,ctime,pname,"dao","Dao");
    }
    /**
     * 生成service接口源文件*/
    private static void createServiceIntf(GroupTemplate gt,String pkname,String ename,String fname,String author,String ctime,String pname) throws FileNotFoundException {
        //1.获取指定模板文件的对象
        Template template=gt.getTemplate("Service.btl");
        //2.生成对应的源码
        createCommonSrc(template,pkname,ename,fname,author,ctime,pname,"service/intf","Service");
    }
    /**
     * 生成service实现类源文件*/
    private static void createServiceImpl(GroupTemplate gt,String pkname,String ename,String fname,String author,String ctime,String pname) throws FileNotFoundException {
        //1.获取指定模板文件的对象
        Template template=gt.getTemplate("ServiceImpl.btl");
        //2.生成指定的文件
        createCommonSrc(template,pkname,ename,fname,author,ctime,pname,"service/impl","ServiceImpl");
    }
    /**
     * 生成controller类源文件*/
    private static void createController(GroupTemplate gt,String pkname,String ename,String fname,String author,String ctime,String pname,String eparam) throws FileNotFoundException {
        //1.获取指定模板文件的对象
        Template template=gt.getTemplate("Controller.btl");
        //2.为模板文件设置数据
        Map<String,Object> params=new HashMap<>();
        params.put("entityName",ename);
        params.put("entityParam",eparam);
        params.put("pkname",pkname);
        params.put("author",author);
        params.put("ctime",ctime);
        params.put("pname",pname);
        //3.将数据和模板绑定
        template.binding(params);
        //4.生成指定的文件
        template.renderTo(new FileOutputStream(fname+"/controller/"+ename+"Controller.java"));
    }


    /**
     * 转换为大驼峰式命名
     */
    private static String parseClassName(String tname){
        if(tname.indexOf("_")>0){
            String[] arr=tname.split("_");
            StringBuffer sb=new StringBuffer();
            for(String s:arr){
                //单个字母，舍弃
                if(s.length()>1){
                    sb.append(parseUpper(s));
                }
            }
            return sb.toString();
        }else{
            return parseUpper(tname);
        }
    }
    /**
     * 转换为小驼峰式命名t_class_name:ClassName ,className
     */
    private static String parseParamName(String tname){
        if(tname.indexOf("_")>0){
            String[] arr=tname.split("_");
            StringBuffer sb=new StringBuffer();
            int first=0;//是不是首个单词
            for(String s:arr){
                //单个字母，舍弃
                if(s.length()>1){
                    if(first==0){
                        sb.append(parseLower(s));//首字母小写
                        first=1;
                    }else {
                        sb.append(parseUpper(s));//首字母大写
                    }
                }
            }
            return sb.toString();
        }else{
            return parseUpper(tname);
        }
    }

    /**
     * 单词的首位字母大写，其他小写，大驼峰*/
    private static String parseUpper(String msg){
        return msg.substring(0,1).toUpperCase()+msg.substring(1).toLowerCase();
    }
    /**
     * 单词的首位字母小写写，其他小写，小驼峰*/
    private static String parseLower(String msg){
        return msg.toLowerCase();
    }
}

